import json
from typing import Any, Union

from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.provider.builtin.did.did_appx import DIDApp
from core.tools.tool.builtin_tool import BuiltinTool


class AnimationsTool(BuiltinTool):
    def _invoke(
        self, user_id: str, tool_parameters: dict[str, Any]
    ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
        app = DIDApp(api_key=self.runtime.credentials['did_api_key'], base_url=self.runtime.credentials['base_url'])

        driver_expressions_str = tool_parameters.get('driver_expressions')
        driver_expressions = json.loads(driver_expressions_str) if driver_expressions_str else None

        config = {
            'stitch': tool_parameters.get('stitch', True),
            'mute': tool_parameters.get('mute'),
            'result_format': tool_parameters.get('result_format') or 'mp4',
        }
        config = {k: v for k, v in config.items() if v is not None and v != ''}

        options = {
            'source_url': tool_parameters['source_url'],
            'driver_url': tool_parameters.get('driver_url'),
            'config': config,
        }
        options = {k: v for k, v in options.items() if v is not None and v != ''}

        if not options.get('source_url'):
            raise ValueError('Source URL is required')

        if config.get('logo_url'):
            if not config.get('logo_x'):
                raise ValueError('Logo X position is required when logo URL is provided')
            if not config.get('logo_y'):
                raise ValueError('Logo Y position is required when logo URL is provided')

        animations_result = app.animations(params=options, wait=True)

        if not isinstance(animations_result, str):
            animations_result = json.dumps(animations_result, ensure_ascii=False, indent=4)

        if not animations_result:
            return self.create_text_message('D-ID animations request failed.')

        return self.create_text_message(animations_result)
